<template>
  <div class="resource-info">
    <div class="panel-search">
      <el-input v-model="keyword" placeholder="请输入关键词">
        <template #suffix>
          <SvgIcon icon-class="ic_搜索" />
        </template>
      </el-input>
    </div>
    <div class="panel-body">
      <div class="panel-body-left">
        <div
          class="sidebar-item"
          v-for="item in category"
          :key="item.code"
          :class="item.code === activeKey ? 'active' : ''"
          @click="() => setActive(item.code)"
        >
          <span>{{ item.title }}</span>
        </div>
      </div>
      <div class="panel-body-right">
        <div v-if="activeKey === '3ds'" class="tips">
          <SvgIcon icon-class="ic_空" class="tips-icon" />
          <div class="tips-text">
            暂不支持3ds直接上传，需要人工转换为gltf格式文件在上传，敬请等待~
          </div>
        </div>
        <div class="grid-wrap">
          <div v-if="activeKey !== '3ds'" class="grid-item import">
            <div class="icon-wrap" @click="onEdit">
              <SvgIcon icon-class="ic_导入1" />
            </div>
            <div class="title">资源导入</div>
          </div>
          <div class="grid-item" v-for="(list, index) in sourceList" :key="index">
            <div class="icon-wrap">
              <img
                v-if="list.resCover"
                class="icon"
                :src="retFilePath(list.resCover)"
                alt=""
                @error="loadImg"
              />
              <img class="icon" v-else src="@/assets/png/bg.png" alt="" />
              <div
                v-if="[2, 53, 63].includes(list.handleState)"
                class="hover-wrap"
                @click="resourceSel(list)"
              >
                <SvgIcon icon-class="ic_plus" class="" />
              </div>
              <!-- 处理失败 -->
              <div v-if="[25, 34, 44, 54].includes(list.handleState)" class="tip-wrap">
                <SvgIcon icon-class="ic_！" class="warn-icon" />
                <div class="tips">处理失败,请删除后重新上传</div>
              </div>
              <!-- 处理中 -->
              <div v-if="[1, 23, 24, 32, 42, 42, 52].includes(list.handleState)" class="tip-wrap">
                <SvgIcon
                  icon-class="ic_处理中"
                  class="warn-icon"
                  style="font-size: 18px; margin-top: 15px"
                />
                <div class="tips" style="color: #faad14">处理中...</div>
              </div>
              <!-- 上传中 -->
              <div v-if="[21, 22].includes(list.handleState)" class="tip-wrap">
                <span class="upload-error">上传失败</span>
                <span class="continue-upload" @click="continueUpload(list)">继续上传</span>
              </div>
            </div>
            <div class="title points" :title="list.fileResName">{{ list.fileResName }}</div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <CreateDialog
    v-if="createDialogShow"
    :resource="selRow"
    :file-type="fileType"
    :is-re-upload="isReUpload"
    @close-handle="createCloseHandle"
  ></CreateDialog>
</template>

<script setup lang="ts">
import { useSceneStore } from '@/store/scene';
import { IResource } from '@/api/resource/types';
import { round, cloneDeep } from 'lodash';
import { messageUtil } from '@jl/element-plus/utils';
import CreateDialog from '@/views/resource/create/index.vue';
import { retFilePath } from '@/utils';

defineOptions({
  name: 'SceneResource',
});

interface IProps {
  data: IResource[];
}
const emits = defineEmits(['refresh']);
const props = withDefaults(defineProps<IProps>(), {
  data: () => [],
});

const category = [
  {
    key: 'all',
    title: '全部',
    code: 'all',
  },
  {
    key: 'OSGB',
    title: 'OSGB',
    code: 'osgb',
  },
  {
    key: 'SHP',
    title: 'SHP',
    code: 'shp',
  },
  {
    key: 'KML',
    title: 'KML',
    code: 'kml',
  },
  {
    key: 'GEOJSON',
    title: 'GEOJSON',
    // code: 'geojson',
    code: 'json',
  },
  {
    key: '3DTILES',
    title: '3DTILES',
    // code: '3dtiles',
    code: '_3dtiles', // 后端文件枚举类型
  },
  {
    key: '3DS',
    title: '3DS',
    code: '3ds',
  },
  {
    key: 'GLTF',
    title: 'GLTF',
    code: 'gltf',
  },
  {
    key: 'TIF-DEM',
    title: 'TIF-DEM',
    // code: 'tif-dem',
    code: 'tif_dem', // 后端文件枚举类型
  },
  {
    key: 'TIF-DOM',
    title: 'TIF-DOM',
    // code: 'tif-dom',
    code: 'tif_dom', // 后端文件枚举类型
  },
  {
    key: 'JLG',
    title: 'JLG',
    code: 'jlg',
  },
];

const keyword = ref('');
const activeKey = ref('all');
const createDialogShow = ref(false);

const sceneStore = useSceneStore();
const fileType = ref('');
const isReUpload = ref(false);
const selRow = ref<null | IResource>(null);
const defalutImgage = require('@/assets/png/bg.png');

const sourceList = computed(() => {
  if (activeKey.value === 'all') {
    return props.data.filter((item) => item.fileResName.indexOf(keyword.value) > -1);
  }
  return props.data.filter(
    (item) => item.fileType === activeKey.value && item.fileResName.indexOf(keyword.value) > -1
  );
});

const setActive = (key: string) => {
  activeKey.value = key;
};
const { cimInstance } = window;
const { Cesium } = window;

function resourceSel(resource: IResource) {
  if (![2, 53, 63].includes(resource.handleState)) {
    messageUtil.warning('资源正在处理中，无法加载');
    return;
  }
  let modelJson: any = null;
  let modelAttr: any = null;
  const centerPosition = cimInstance.api.screenToDegrees({
    x: round(document.body.offsetWidth / 2),
    y: round(document.body.offsetHeight / 2),
  });
  if (resource.fileType === 'gltf') {
    modelJson = {
      enable: true,
      name: resource.fileResName + '_gltf_' + Math.random().toString().split('.')[1],
      type: 'gltfmodel',
      positions: [[centerPosition[0], centerPosition[1], 5]],
      dataSourceUrl: retFilePath(resource.resUrl),
      scale: 1,
      rotation: [0, 0, 0],
      createType: 'primitive',
      enablePbr: true,
      shadowsType: 1,
    };
    modelAttr = {
      position: modelJson.positions[0],
      translation: [0, 0, 0],
      rotation: modelJson.rotation,
      scale: modelJson.scale,
      color: '',
    };
  }
  if (resource.fileType === '_3dtiles') {
    modelJson = {
      enable: true,
      index: 3,
      name: resource.fileResName + '_tileset_' + Math.random().toString().split('.')[1], // 'tileset',
      type: 'tileset', // 对应图层 3dtiles
      dataSourceUrl: retFilePath(resource.resUrl),
      offset: [0, 0, 0],
      rotation: [0, 0, 0],
      scale: 1,
      zoomTo: true,
      customShader: {
        shaderType: 'unlit',
        uniforms: {},
      },
    };
    modelAttr = {
      offset: undefined,
      rotation: undefined,
      scale: undefined,
      color: '',
      material: {
        brightness: 1,
        contrast: 1,
        hue: 0,
        saturation: 1,
        gamma: 1,
      },
    };
  }
  if (resource.fileType === 'json') {
    Cesium.Resource.fetchJson({ url: retFilePath(resource.resUrl) }).then((res: any) => {
      const type = res?.features[0].geometry.type || '';
      let jsonType = '';
      switch (type) {
        case 'Point':
          jsonType = 'point';
          modelJson = {
            enable: true,
            type: jsonType,
            name: resource.fileResName + '_point_' + Math.random().toString().split('.')[1], // 'tileset',
            dataSourceUrl: retFilePath(resource.resUrl),
            size: 10,
            // heightReference: "CLAMP_TO_GROUND",
            color: '#FF0000',
            outlineColor: '#FFFF00',
            outlineWidth: 1,
            // scaleByDistanceArray: [10000, 0.5, 50000, 2],
            // translucencyByDistanceArray: [10000, 0.5, 50000, 1],
            // disableDepthTestDistance: Number.POSITIVE_INFINITY,
            // minDisplayDistance: 0,
            // maxDisplayDistance: 10000000,
            // height: 1,
          };
          modelAttr = {
            // size: 10,
            color: '#FF0000',
            outlineColor: '#FFFF00',
            outlineWidth: 1,
            // scaleByDistanceArray: undefined,
            // translucencyByDistanceArray: undefined,
            // minDisplayDistance: undefined,
            // maxDisplayDistance: undefined,
            // height: undefined,
          };
          break;

        case 'LineString':
          jsonType = 'polyline';
          modelJson = {
            enable: true,
            name: resource.fileResName + '_polyline_' + Math.random().toString().split('.')[1], // 'tileset',
            type: jsonType,
            dataSourceUrl: retFilePath(resource.resUrl),
            color: '#FFFF00',
            width: 10,
            createType: 'entity',
            // minDisplayDistance: 1000,
            // maxDisplayDistance: 50000
          };
          modelAttr = {
            color: '#FF0000',
            width: 10,
            // minDisplayDistance: 1000,
            // maxDisplayDistance: 50000
          };
          break;

        case 'MultiPolygon':
          jsonType = 'polygon';
          modelJson = {
            enable: true,
            name: resource.fileResName + '_polygon_' + Math.random().toString().split('.')[1], // 'tileset',
            type: 'polygon',
            dataSourceUrl: retFilePath(resource.resUrl),
            fillColor: '#FF0000',
            createType: 'entity',
          };
          modelAttr = {
            fillColor: '#FF0000',
            minDisplayDistance: 0,
            maxDisplayDistance: undefined,
          };
          break;

        default:
          jsonType = '';
          break;
      }
      executeFunc(modelJson, resource, modelAttr);
    });
    return;
  }
  if (resource.fileType === 'jlg') {
    const fileName = resource.resUrl.split('/').pop();
    modelJson = {
      enable: true,
      name: resource.fileResName + '_bimModel_' + Math.random().toString().split('.')[1],
      type: 'bimModel',
      url: retFilePath(resource.resUrl),
      texturePath: retFilePath(resource.resUrl.replace(fileName, 'textures/')),
      showStats: false,
      translation: [centerPosition[0], centerPosition[1], 5],
      rotation: [0, 0, 0],
      scale: 1,
      loaderWorkerUrl: '/cimupresource/shouqiandemo/zhengtai/bim/upbim.worker.js',
      unit: 'm',
      dracoUrl: '/cimupresource/shouqiandemo/zhengtai/bim/draco_decoder.js',
    };

    console.log('------jlg--------', modelJson.translation);
    modelAttr = {
      position: modelJson.transition,
      translation: [0, 0, 0],
      rotation: [0, 0, 0],
      scale: 1,
      color: '',
    };
  }
  if (resource.fileType === 'tif_dom') {
    if (resource.configJson) {
      const configJson = JSON.parse(resource.configJson);
      if (configJson.Method === 'XyzCut') {
        debugger;
        const extent = configJson.Extent ? getExtent(configJson.Extent) : [];
        modelJson = {
          enable: true,
          name: resource.fileResName + '_image_' + Math.random().toString().split('.')[1],
          type: 'image',
          source: 'fileserver',
          dataSourceUrl: retFilePath(resource.resUrl),
          maximumLevel: 18,
          minimumLevel: 1,
          brightness: 1,
          saturation: 1,
          contrast: 1,
          extent: extent,
        };
      } else {
        const extent = configJson.Extent ? getExtent(configJson.Extent) : [];
        console.log('--影像图层范围--', extent);
        const arr = resource.resUrl.split('?');
        const url = arr[0],
          param: any = {};
        if (arr[1] && arr[1].split('&').length > 0) {
          arr[1].split('&').forEach((ele: string) => {
            param[ele.split('=')[0]] = ele.split('=')[1];
          });
        }
        console.log(url, param);
        modelJson = {
          enable: true,
          name: resource.fileResName + '_image_' + Math.random().toString().split('.')[1],
          type: 'image',
          source: 'geoserver',
          dataSourceUrl: `/${url}?`,
          layers: param.layers || '',
          format: param.format || 'image/png',
          srs: param.srs || 'EPSG:4326',
          serviceVer: param.serviceVer || '1.1.0',
          maximumLevel: 18,
          minimumLevel: 1,
          brightness: 1,
          saturation: 1,
          contrast: 1,
          extent,
        };
      }
    } else {
      return;
    }
    modelAttr = {
      brightness: 1,
      saturation: 1,
      contrast: 1,
    };
  }
  if (resource.fileType === 'tif_dem') {
    if (resource.configJson) {
      const configJson = JSON.parse(resource.configJson);
      if (configJson.Method === 'LayerRele') {
        const extent = configJson.Extent ? getExtent(configJson.Extent) : [];
        console.log('--影像图层范围--', extent);
        const arr = resource.resUrl.split('?');
        const url = arr[0],
          param: any = {};
        if (arr[1] && arr[1].split('&').length > 0) {
          arr[1].split('&').forEach((ele: string) => {
            param[ele.split('=')[0]] = ele.split('=')[1];
          });
        }
        console.log(url, param);
        modelJson = {
          enable: true,
          name: resource.fileResName + '_image_' + Math.random().toString().split('.')[1],
          type: 'image',
          source: 'geoserver',
          dataSourceUrl: `/${url}?`,
          layers: param.layers || '',
          format: param.format || 'image/png',
          srs: param.srs || 'EPSG:4326',
          serviceVer: param.serviceVer || '1.1.0',
          maximumLevel: 18,
          minimumLevel: 1,
          brightness: 1,
          saturation: 1,
          contrast: 1,
          extent,
        };
      }
    } else {
      return;
    }
    modelAttr = {
      brightness: 1,
      saturation: 1,
      contrast: 1,
    };
  }
  executeFunc(modelJson, resource, modelAttr);
}

function getExtent(str: string) {
  let extent = [];
  if (str.includes('EPSG')) {
    extent = str.replace('[EPSG:4326]', '').trim().split(',');
  } else {
    extent = str.trim().split(',');
  }
  extent = extent.map((v: string) => Number(v)).sort((a: number, b: number) => a - b);
  const Xmin = extent[2],
    Xmax = extent[3],
    Ymin = extent[0],
    Ymax = extent[1];

  return [Xmin, Ymin, Xmax, Ymax];
}

function executeFunc(modelJson: any, resource: IResource, modelAttr: any) {
  if (!modelJson) {
    return;
  }
  const layerParam: any = {
    code: Math.random().toString().split('.')[1],
    show: true,
    json: modelJson,
    name: resource.fileResName,
    layerName: modelJson.name,
    desc: '',
    type: modelJson.type,
    attr: {
      position: [0, 0, 0],
    },
    resourceId: resource.resourceId,
  };
  if (modelAttr) {
    layerParam.attr = modelAttr;
  }
  cimInstance.api.closeSceneOffset();
  sceneStore.layerList.unshift(layerParam);
  console.log(sceneStore.layerList);

  if (sceneStore.sourceType === 'layerImport') {
    sceneStore.sourceType = '';
    sceneStore.leftPanelVisible = true;
    sceneStore.leftPanelActive = 'layer';
  }
}

const onEdit = () => {
  if (activeKey.value !== 'all') {
    fileType.value = activeKey.value;
  } else {
    fileType.value = '';
  }
  createDialogShow.value = true;
};

const createCloseHandle = (refresh: boolean) => {
  createDialogShow.value = false;
  emits('refresh');
};

const continueUpload = async (item: IResource) => {
  isReUpload.value = true;
  selRow.value = item || null;
  createDialogShow.value = true;
};

const loadImg = (e: any) => {
  e.target.src = defalutImgage;
};
</script>

<style lang="less" scoped>
.resource-info {
  height: 100%;

  .panel-search {
    padding: 10px;
    background: #171a1f;
    --el-fill-color-blank: #202329;
    --el-border-color: rgba(69, 72, 81, 0.6);
    --el-text-color-regular: #fff;
    .el-input__inner ::placeholder {
      color: #9a9a9a;
    }
  }
  .panel-body {
    display: flex;
    height: calc(100% - 60px);
    .panel-body-left {
      width: 98px;
      background: #14161a;
      overflow-y: auto;
      .sidebar-item {
        width: 100%;
        padding: 15px 6px 15px 15px;
        font-weight: 400;
        color: #ffffff;
        font-size: 14px;
        cursor: pointer;
        &.active {
          color: var(--el-color-primary);
          background: #0a0b0d;
        }
      }
    }
    .panel-body-right {
      flex: 1;
      padding: 20px 20px 20px 16px;
      overflow-y: auto;
      .grid-wrap {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        column-gap: 20px;
        row-gap: 20px;
        .grid-item {
          display: flex;
          flex-direction: column;
          align-items: center;
          cursor: pointer;
          .icon-wrap {
            position: relative;
            width: 100px;
            height: 84px;
            border-radius: 8px;
            overflow: hidden;
            background: #202329;
            .svg-icon {
              font-size: 42px;
              margin-right: 0px;
              position: absolute;
              top: 50%;
              left: 50%;
              transform: translate(-50%, -50%);
            }
            .tip-wrap {
              position: absolute;
              left: 0;
              top: 0;
              width: 100%;
              height: 100%;
              display: flex;
              align-items: center;
              justify-content: center;
              flex-direction: column;
              background: rgba(22, 22, 22, 0.86);

              .warn-icon {
                position: relative;
                width: 100px;
                top: 0;
                left: 0;
                font-size: 20px;
                transform: none;
              }

              .tips {
                margin-top: 5px;
                width: 60px;
                height: 28px;
                font-size: 12px;
                font-family: PingFangSC-Regular, PingFang SC;
                font-weight: 400;
                color: #ff5454;
                line-height: 14px;
                display: -webkit-box;
                text-align: center;
                overflow: hidden;
                text-overflow: ellipsis;
                -webkit-line-clamp: 2;
                -webkit-box-orient: vertical;
              }
              .upload-error {
                height: 14px;
                font-size: 12px;
                font-family: PingFangSC-Regular, PingFang SC;
                font-weight: 400;
                color: #ff5454;
                line-height: 14px;
              }

              .continue-upload {
                width: 72px;
                height: 24px;
                line-height: 24px;
                margin-top: 4px;
                border-radius: 4px;
                border: 1px solid #0560fd;
                text-align: center;
                color: #0560fd;
                cursor: pointer;
                transition: background-color 0.3s;
              }
            }

            .hover-wrap {
              position: absolute;
              left: 0;
              top: 0;
              width: 100%;
              height: 100%;
              display: none;
              background: rgba(22, 22, 22, 0.86);
            }
          }
          .icon {
            width: 100%;
            height: 100%;
            object-fit: cover;
          }
          .title {
            width: 100px;
            margin-top: 10px;
            text-align: center;
          }
          &.import {
            .icon {
            }
          }
          &:hover {
            .hover-wrap {
              display: flex;
              align-items: center;
              justify-content: center;
              flex-direction: column;

              .warn-icon {
                font-size: 20px;
                position: relative;
                transform: none;
                top: 0;
                left: 0;
                width: 100px;
              }

              .tips {
                margin-top: 5px;
                width: 60px;
                height: 28px;
                font-size: 12px;
                font-family: PingFangSC-Regular, PingFang SC;
                font-weight: 400;
                color: #ff5454;
                line-height: 14px;
                display: -webkit-box;
                text-align: center;
                overflow: hidden;
                text-overflow: ellipsis;
                -webkit-line-clamp: 2;
                -webkit-box-orient: vertical;
              }
            }
          }
        }
      }
      .tips {
        display: flex;
        flex-direction: column;
        align-items: center;
        .tips-icon {
          font-size: 56px;
        }
        .tips-text {
          font-size: 12px;
          width: 210px;
          font-family: PingFangSC-Regular, PingFang SC;
          color: #9a9a9a;
          text-align: center;
          line-height: 17px;
          height: 34px;
          margin-top: 5px;
        }
      }
    }
  }
}
</style>
